iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Software Development

或躍在淵的CAE: 讓咱們用Python會一會ANSA + LS-DYNA系列 第 17

[Day17] - Box Drop Project精進計畫(9) - 實作Context Manager用以簡化base.ImportV1使用流程

  • 分享至 

  • xImage
  •  

base.ImportV1也太難用了吧...

要記得startbuildfinish的順序,又要記得所產生的Entities只能在buildfinish間取得。

有沒有辦法改寫一下code,給二次開發的兄弟們,一個比較好的使用體驗呢?

是滴!諸位的心聲我們都聽到了,下面就不藏私地跟大家分享我們的解法。

Context Manager

  • 建立一個class-basedContext Manager,取名為MyImportV1class
  • 建立一個名為_attrsclass variable,其型態為tuple,裡面儲存的三個element,是我們之後想取得的Entity
  • __init__中建立一個self.a,是一個base.ImportV1instance
  • __enter__中,呼叫self.a.start,並return self.a。這一步可謂是關鍵,這邊returnobject,會被當作with ooo as xxx中的xxx,也就是我們在Context Manager中,真正會使用的 object。大部分的Context Manager會在這邊return self,但我們想於Context Manager中借助base.ImportV1,所以必須return self.a
  • __enter__,先呼叫self.a.build,並於最後呼叫self.a.finish。在buildfinish之間,就是我們可以動手腳的地方,因為我們只能在此取得產生的Entity。我們針對self._attrs打一個迴圈,透過getattr(self.a, _attr)得到所產生的Entity,再透過setattr(self, _attr, attr),將這些Entity各自存為一個instance variable。如此一來,於主程式中我們就能透過MyImportV1instance來取得這些Entity了。
  • 如果有點難理解的話,可以參考我們於主程式中如何使用。
# ctxmgr.py
from ansa import base


class MyImportV1:
    _attrs = ('nodes', 'shells', 'solids')

    def __init__(self):
        self.a = base.ImportV1()

    def __enter__(self):
        self.a.start()
        return self.a

    def __exit__(self, exc_type, exc_value, exc_tb):
        self.a.build()
        for _attr in self._attrs:
            attr = getattr(self.a, _attr)
            setattr(self, _attr, attr)
        self.a.finish()

主程式

經過一番乾坤大挪移後:

  • 我們終於不用再辛苦地手動startbuildfinish了。
  • plate_import_v1box_import_v1可以於Context Manager的範圍外,取得nodeshellssolids了。
# box_drop.py
def main():
    deck = constants.LSDYNA
    set_deck_to(deck)

    # plate
    plate_prop = create_sec()
    plate_mat_prop_id = plate_prop._id
    plate_set = create_set(plate_prop, 'plate', deck=deck)
    l_p, w_p, en1_p, en2_p = 100, 100, 10, 10
    z_elv_p, move_xy_p, rot_angle_p = 0, None, None

    plate_import_v1 = MyImportV1()
    with plate_import_v1 as import_v1:
        create_plate_v1(import_v1,
                        l_p,
                        w_p,
                        en1_p,
                        en2_p,
                        plate_mat_prop_id,
                        z_elv=z_elv_p,
                        move_xy=move_xy_p,
                        rot_angle=rot_angle_p,
                        deck=deck)
    plate_nodes = plate_import_v1.nodes
    plate_shells = plate_import_v1.shells

    # box
    box_prop = create_sec(sec_type=SecType.SECTION_SOLID)
    box_mat_prop_id = box_prop._id
    box_set = create_set(box_prop, 'box', deck=deck)

    l_b, w_b, h_b, en1_b, en2_b, en3_b = 50, 50, 50, 10, 10, 10
    z_elv_b, move_xy_b, rot_angle_b = 5, (50, 20), 45

    box_import_v1 = MyImportV1()
    with box_import_v1 as import_v1:
        create_box_v1(import_v1,
                      l_b,
                      w_b,
                      h_b,
                      en1_b,
                      en2_b,
                      en3_b,
                      box_mat_prop_id,
                      z_elv=z_elv_b,
                      move_xy=move_xy_b,
                      rot_angle=rot_angle_b,
                      deck=deck)
    box_nodes = box_import_v1.nodes
    box_solids = box_import_v1.solids

小結

[Day18]我們準備暫時抽離這不斷精進,不斷改code的十天,來寫點tests吧!

Code

本日程式碼傳送門


上一篇
[Day16] - Box Drop Project精進計畫(8) - 使用base.ImportV1
下一篇
[Day18] - Box Drop Project精進計畫(10) - Test
系列文
或躍在淵的CAE: 讓咱們用Python會一會ANSA + LS-DYNA30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言